using System.Collections.Generic;
using HTCollections.Examples.JobSystem;
using HTCollections.Unsafe;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;

namespace HTCollections.Examples
{
    public class JobSystemExample : MonoBehaviour
    {
        public int JobCount = 4;

        void ChangeValue(ref int value, int newValue)
        {
            value = newValue;
        }

        void Update()
        {
            if (Input.GetKeyDown(KeyCode.Q))
            {
                UnsafeHashMap<int, int> map = new UnsafeHashMap<int, int>(4, Allocator.TempJob);
                map.Add(1, 4);
                map.Add(2, 5);
                map.Add(3, 2);
                map.Add(4, 1);
                map.Add(5, 0);

                UnsafeList<int> intLst = new UnsafeList<int>(4, Allocator.TempJob);
                intLst.Add(2017);
                intLst.Add(2018);
                intLst.Add(2019);
                intLst.Add(2020);
                intLst.Add(2021);
                intLst.Add(2022);
                intLst.Add(2023);

                UnsafePriorityQueue<SubTestData1> priorityQueue =
                    new UnsafePriorityQueue<SubTestData1>(5, false, Allocator.TempJob);
                priorityQueue.Enqueue(new SubTestData1()
                {
                    Value1 = 6,
                    Enable = false,
                    Value2 = 400,
                    IntList = intLst,
                }, 4);
                priorityQueue.Enqueue(new SubTestData1()
                {
                    Value1 = 5,
                    Enable = true,
                    Value2 = 900,
                    IntList = intLst,
                }, 9);
                priorityQueue.Enqueue(new SubTestData1()
                {
                    Value1 = 4,
                    Enable = false,
                    Value2 = 200,
                    IntList = intLst,
                }, 2);
                priorityQueue.Enqueue(new SubTestData1()
                {
                    Value1 = 3,
                    Enable = true,
                    Value2 = 700,
                    IntList = intLst,
                }, 7);
                priorityQueue.Enqueue(new SubTestData1()
                {
                    Value1 = 2,
                    Enable = false,
                    Value2 = 1100,
                    IntList = intLst,
                }, 11);
                priorityQueue.Enqueue(new SubTestData1()
                {
                    Value1 = 1,
                    Enable = true,
                    Value2 = 500,
                    IntList = intLst,
                }, 5);


                ChangeValue(ref map.GetElementRef(2), 3);
                List<JobDataWrap<int>> results = new List<JobDataWrap<int>>(JobCount);
                for (int i = 0; i < JobCount; i++)
                {
                    results.Add(new JobDataWrap<int>(Allocator.TempJob));
                }

                NativeArray<JobHandle> jobHandles = new NativeArray<JobHandle>(JobCount, Allocator.TempJob);
                for (int i = 0; i < JobCount; i++)
                {
                    var job = new TestJob1
                    {
                        Data1 = new TestData1
                        {
                            Value1 = i,
                            Map = map,
                            PriorityQueue = priorityQueue,
                        },
                        Data = results[i],
                    };
                    jobHandles[i] = job.Schedule();
                }

                JobHandle.CompleteAll(jobHandles);
                for (int i = 0; i < JobCount; i++)
                {
                    Debug.Log($"Result[{i}]: {results[i].Value}"); //0, 204, 203, 202
                }

                jobHandles.Dispose();
                map.Dispose();
                priorityQueue.Dispose();
                intLst.Dispose();
                for (int i = 0; i < JobCount; i++)
                    results[i].Dispose();
            }

            if (Input.GetKeyDown(KeyCode.W))
            {
                var map = new UnsafeHashMap<int, int>(4, Allocator.TempJob);
                map.Add(111, 1);
                map.Add(712, 2);
                map.Add(894, 3);
                map.Add(146, 4);

                var list = new UnsafeList<int>(4, Allocator.TempJob);
                list.Add(1);
                list.Add(2);
                list.Add(3);
                list.Add(4);

                //必须包裹一层, 来存储 struct 的指针地址
                var mapWrap = new JobDataWrap<UnsafeHashMap<int, int>>(map, Allocator.TempJob);
                var listWrap = new JobDataWrap<UnsafeList<int>>(list, Allocator.TempJob);

                TestJob2 job = new TestJob2()
                {
                    Map = mapWrap,
                    List = listWrap,
                };
                job.Schedule().Complete();
                map = mapWrap.Value;
                list = listWrap.Value;
                foreach (var item in map)
                    Debug.Log($"{item.Key}, {item.Value}");
                foreach (var item in list)
                    Debug.Log($"{item}");
                map.Dispose();
                list.Dispose();
                mapWrap.Dispose();
                listWrap.Dispose();
            }
        }
    }
}